import tkinter as tk
from tkinter import ttk, messagebox
from PIL import Image, ImageTk, ImageDraw
import numpy as np
import os
import time
import cv2
import face_recognition

class FaceRecognitionApp:
    def __init__(self, root):
        self.root = root
        self.root.title("人脸识别与健康分析系统")
        self.root.geometry("900x650")
        self.root.resizable(True, True)

        # 设置中文字体
        self.font = ("SimHei", 12)
        self.small_font = ("SimHei", 10)
        self.large_font = ("SimHei", 14, "bold")

        # 初始化摄像头和人脸识别
        self.video_capture = None
        self.running = False
        self.face_locations = []
        self.face_encodings = []
        self.face_names = []
        self.health_analysis = []

        # 创建UI
        self.create_widgets()
        # 绑定窗口关闭事件
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)

    def create_widgets(self):
        # 主框架
        main_frame = ttk.Frame(self.root, padding=10)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 顶部控制区
        control_frame = ttk.LabelFrame(main_frame, text="控制", padding=10)
        control_frame.pack(fill=tk.X, pady=(0, 10))

        # 开始/停止按钮
        self.start_button = ttk.Button(control_frame, text="开始摄像头", command=self.start_camera)
        self.start_button.pack(side=tk.LEFT, padx=5)

        self.stop_button = ttk.Button(control_frame, text="停止摄像头", command=self.stop_camera, state=tk.DISABLED)
        self.stop_button.pack(side=tk.LEFT, padx=5)

        # 摄像头选择
        ttk.Label(control_frame, text="摄像头ID:", font=self.small_font).pack(side=tk.LEFT, padx=(20, 5))
        self.camera_id_var = tk.StringVar(value="0")
        camera_entry = ttk.Entry(control_frame, textvariable=self.camera_id_var, width=5)
        camera_entry.pack(side=tk.LEFT)

        # 显示区域
        display_frame = ttk.Frame(main_frame)
        display_frame.pack(fill=tk.BOTH, expand=True)

        # 视频显示区域
        self.video_frame = ttk.LabelFrame(display_frame, text="摄像头画面", padding=10)
        self.video_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))

        self.video_label = ttk.Label(self.video_frame)
        self.video_label.pack(fill=tk.BOTH, expand=True)

        # 健康分析区域
        self.health_frame = ttk.LabelFrame(display_frame, text="健康分析", padding=10, width=250)
        self.health_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=False)

        self.health_text = tk.Text(self.health_frame, height=15, width=30, font=self.small_font)
        self.health_text.pack(fill=tk.BOTH, expand=True, pady=5)
        self.health_text.insert(tk.END, "等待检测...\n")
        self.health_text.config(state=tk.DISABLED)

        # 状态栏
        self.status_var = tk.StringVar(value="就绪")
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)

    def start_camera(self):
        try:
            camera_id = int(self.camera_id_var.get())
            self.video_capture = cv2.VideoCapture(camera_id)
            if not self.video_capture.isOpened():
                raise Exception(f"无法打开摄像头 ID: {camera_id}")

            self.running = True
            self.start_button.config(state=tk.DISABLED)
            self.stop_button.config(state=tk.NORMAL)
            self.status_var.set(f"正在使用摄像头 ID: {camera_id}")
            self.update_frame()
        except Exception as e:
            messagebox.showerror("摄像头错误", str(e))
            self.status_var.set("就绪")

    def stop_camera(self):
        self.running = False
        if self.video_capture is not None:
            self.video_capture.release()
        # 检查按钮是否存在再配置状态
        if hasattr(self, 'start_button') and self.start_button.winfo_exists():
            self.start_button.config(state=tk.NORMAL)
        if hasattr(self, 'stop_button') and self.stop_button.winfo_exists():
            self.stop_button.config(state=tk.DISABLED)
        if hasattr(self, 'status_var'):
            self.status_var.set("就绪")
        if hasattr(self, 'video_label'):
            self.video_label.config(image='')
        if hasattr(self, 'health_text') and self.health_text.winfo_exists():
            self.health_text.config(state=tk.NORMAL)
            self.health_text.delete(1.0, tk.END)
            self.health_text.insert(tk.END, "等待检测...\n")
            self.health_text.config(state=tk.DISABLED)

    def update_frame(self):
        if not self.running:
            return

        ret, frame = self.video_capture.read()
        if ret:
            # 处理帧
            rgb_frame = frame[:, :, ::-1]  # 转换为RGB

            # 只检测人脸位置，不获取编码
            try:
                self.face_locations = face_recognition.face_locations(rgb_frame)
                # 清空编码列表
                self.face_encodings = []
            except Exception as e:
                print(f"人脸检测错误: {e}")
                self.face_locations = []

            # 清除之前的预测
            self.face_names = []
            self.health_analysis = []

            # 处理每个人脸
            for (top, right, bottom, left) in self.face_locations:
                # 这里简化处理，实际应用中可以添加人脸识别数据库
                self.face_names.append("未知")

                # 生成健康分析
                self.generate_health_analysis()

                # 绘制矩形框（绿色），移除标签
                cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)

            # 更新健康分析文本
            self.update_health_text()

            # 显示处理后的帧
            img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            img = Image.fromarray(img)
            imgtk = ImageTk.PhotoImage(image=img)
            self.video_label.imgtk = imgtk
            self.video_label.config(image=imgtk)

        # 继续更新
        self.root.after(10, self.update_frame)

    def generate_health_analysis(self):
        # 基本健康分析，不依赖性别和年龄
        analysis = {
            "健康建议": [
                "保持均衡饮食",
                "保证充足睡眠",
                "定期进行体检",
                "保持适量运动"
            ]
        }

        self.health_analysis.append(analysis)

    def update_health_text(self):
        self.health_text.config(state=tk.NORMAL)
        self.health_text.delete(1.0, tk.END)

        if not self.health_analysis:
            self.health_text.insert(tk.END, "未检测到人脸...\n")
        else:
            for i, analysis in enumerate(self.health_analysis):
                self.health_text.insert(tk.END, f"人脸 {i+1}:\n")
                self.health_text.insert(tk.END, "  健康建议:\n")
                for suggestion in analysis['健康建议']:
                    self.health_text.insert(tk.END, f"    - {suggestion}\n")
                self.health_text.insert(tk.END, "\n")

        self.health_text.config(state=tk.DISABLED)

    def on_closing(self):
        """处理窗口关闭事件"""
        self.stop_camera()
        self.root.destroy()

    def __del__(self):
        # 避免在析构函数中访问可能已销毁的tkinter组件
        pass

if __name__ == "__main__":
    # 检查是否安装了必要的库
    try:
        import cv2
        import face_recognition
    except ImportError as e:
        root = tk.Tk()
        root.withdraw()  # 隐藏主窗口
        messagebox.showerror("库缺失", f'''缺少必要的库: {str(e)}

请运行以下命令安装:

pip install opencv-python face_recognition''')
        root.destroy()
    else:
        root = tk.Tk()
        app = FaceRecognitionApp(root)
        root.mainloop()